In [1]:
%load_ext autoreload
%autoreload 2
%env CUDA_VISIBLE_DEVICES=3
env: CUDA_VISIBLE_DEVICES=3

Download packages if in Google Colab¶

In [2]:
colab_requirements = [
    "pip install librosa",
    "pip install noisereduce",
    "pip install soundfile",

]

import sys, subprocess

def run_subprocess_command(cmd):
    # run the command
    process = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
    # print the output
    for line in process.stdout:
        print(line.decode().strip())

IN_COLAB = "google.colab" in sys.modules
if IN_COLAB:
    for i in colab_requirements:
        run_subprocess_command(i)
Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/
Requirement already satisfied: librosa in /usr/local/lib/python3.9/dist-packages (0.8.1)
Requirement already satisfied: resampy>=0.2.2 in /usr/local/lib/python3.9/dist-packages (from librosa) (0.4.2)
Requirement already satisfied: numpy>=1.15.0 in /usr/local/lib/python3.9/dist-packages (from librosa) (1.23.1)
Requirement already satisfied: decorator>=3.0.0 in /usr/local/lib/python3.9/dist-packages (from librosa) (4.4.2)
Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.9/dist-packages (from librosa) (23.0)
Requirement already satisfied: soundfile>=0.10.2 in /usr/local/lib/python3.9/dist-packages (from librosa) (0.12.1)
Requirement already satisfied: scikit-learn!=0.19.0,>=0.14.0 in /usr/local/lib/python3.9/dist-packages (from librosa) (1.2.1)
Requirement already satisfied: joblib>=0.14 in /usr/local/lib/python3.9/dist-packages (from librosa) (1.2.0)
Requirement already satisfied: numba>=0.43.0 in /usr/local/lib/python3.9/dist-packages (from librosa) (0.53.0)
Requirement already satisfied: scipy>=1.0.0 in /usr/local/lib/python3.9/dist-packages (from librosa) (1.10.1)
Requirement already satisfied: pooch>=1.0 in /usr/local/lib/python3.9/dist-packages (from librosa) (1.7.0)
Requirement already satisfied: audioread>=2.0.0 in /usr/local/lib/python3.9/dist-packages (from librosa) (3.0.0)
Requirement already satisfied: llvmlite<0.37,>=0.36.0rc1 in /usr/local/lib/python3.9/dist-packages (from numba>=0.43.0->librosa) (0.36.0)
Requirement already satisfied: setuptools in /usr/local/lib/python3.9/dist-packages (from numba>=0.43.0->librosa) (57.4.0)
Requirement already satisfied: platformdirs>=2.5.0 in /usr/local/lib/python3.9/dist-packages (from pooch>=1.0->librosa) (3.1.0)
Requirement already satisfied: requests>=2.19.0 in /usr/local/lib/python3.9/dist-packages (from pooch>=1.0->librosa) (2.25.1)
Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.9/dist-packages (from scikit-learn!=0.19.0,>=0.14.0->librosa) (3.1.0)
Requirement already satisfied: cffi>=1.0 in /usr/local/lib/python3.9/dist-packages (from soundfile>=0.10.2->librosa) (1.15.1)
Requirement already satisfied: pycparser in /usr/local/lib/python3.9/dist-packages (from cffi>=1.0->soundfile>=0.10.2->librosa) (2.21)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in /usr/local/lib/python3.9/dist-packages (from requests>=2.19.0->pooch>=1.0->librosa) (1.26.14)
Requirement already satisfied: chardet<5,>=3.0.2 in /usr/local/lib/python3.9/dist-packages (from requests>=2.19.0->pooch>=1.0->librosa) (4.0.0)
Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.9/dist-packages (from requests>=2.19.0->pooch>=1.0->librosa) (2.10)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.9/dist-packages (from requests>=2.19.0->pooch>=1.0->librosa) (2022.12.7)
Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/
Requirement already satisfied: noisereduce in /usr/local/lib/python3.9/dist-packages (2.0.1)
Requirement already satisfied: tqdm in /usr/local/lib/python3.9/dist-packages (from noisereduce) (4.65.0)
Requirement already satisfied: matplotlib in /usr/local/lib/python3.9/dist-packages (from noisereduce) (3.5.3)
Requirement already satisfied: numpy in /usr/local/lib/python3.9/dist-packages (from noisereduce) (1.23.1)
Requirement already satisfied: scipy in /usr/local/lib/python3.9/dist-packages (from noisereduce) (1.10.1)
Requirement already satisfied: librosa in /usr/local/lib/python3.9/dist-packages (from noisereduce) (0.8.1)
Requirement already satisfied: audioread>=2.0.0 in /usr/local/lib/python3.9/dist-packages (from librosa->noisereduce) (3.0.0)
Requirement already satisfied: joblib>=0.14 in /usr/local/lib/python3.9/dist-packages (from librosa->noisereduce) (1.2.0)
Requirement already satisfied: soundfile>=0.10.2 in /usr/local/lib/python3.9/dist-packages (from librosa->noisereduce) (0.12.1)
Requirement already satisfied: scikit-learn!=0.19.0,>=0.14.0 in /usr/local/lib/python3.9/dist-packages (from librosa->noisereduce) (1.2.1)
Requirement already satisfied: resampy>=0.2.2 in /usr/local/lib/python3.9/dist-packages (from librosa->noisereduce) (0.4.2)
Requirement already satisfied: numba>=0.43.0 in /usr/local/lib/python3.9/dist-packages (from librosa->noisereduce) (0.53.0)
Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.9/dist-packages (from librosa->noisereduce) (23.0)
Requirement already satisfied: pooch>=1.0 in /usr/local/lib/python3.9/dist-packages (from librosa->noisereduce) (1.7.0)
Requirement already satisfied: decorator>=3.0.0 in /usr/local/lib/python3.9/dist-packages (from librosa->noisereduce) (4.4.2)
Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.9/dist-packages (from matplotlib->noisereduce) (0.11.0)
Requirement already satisfied: pillow>=6.2.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib->noisereduce) (8.4.0)
Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib->noisereduce) (1.4.4)
Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.9/dist-packages (from matplotlib->noisereduce) (2.8.2)
Requirement already satisfied: pyparsing>=2.2.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib->noisereduce) (3.0.9)
Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib->noisereduce) (4.39.0)
Requirement already satisfied: llvmlite<0.37,>=0.36.0rc1 in /usr/local/lib/python3.9/dist-packages (from numba>=0.43.0->librosa->noisereduce) (0.36.0)
Requirement already satisfied: setuptools in /usr/local/lib/python3.9/dist-packages (from numba>=0.43.0->librosa->noisereduce) (57.4.0)
Requirement already satisfied: requests>=2.19.0 in /usr/local/lib/python3.9/dist-packages (from pooch>=1.0->librosa->noisereduce) (2.25.1)
Requirement already satisfied: platformdirs>=2.5.0 in /usr/local/lib/python3.9/dist-packages (from pooch>=1.0->librosa->noisereduce) (3.1.0)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.9/dist-packages (from python-dateutil>=2.7->matplotlib->noisereduce) (1.15.0)
Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.9/dist-packages (from scikit-learn!=0.19.0,>=0.14.0->librosa->noisereduce) (3.1.0)
Requirement already satisfied: cffi>=1.0 in /usr/local/lib/python3.9/dist-packages (from soundfile>=0.10.2->librosa->noisereduce) (1.15.1)
Requirement already satisfied: pycparser in /usr/local/lib/python3.9/dist-packages (from cffi>=1.0->soundfile>=0.10.2->librosa->noisereduce) (2.21)
Requirement already satisfied: chardet<5,>=3.0.2 in /usr/local/lib/python3.9/dist-packages (from requests>=2.19.0->pooch>=1.0->librosa->noisereduce) (4.0.0)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in /usr/local/lib/python3.9/dist-packages (from requests>=2.19.0->pooch>=1.0->librosa->noisereduce) (1.26.14)
Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.9/dist-packages (from requests>=2.19.0->pooch>=1.0->librosa->noisereduce) (2.10)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.9/dist-packages (from requests>=2.19.0->pooch>=1.0->librosa->noisereduce) (2022.12.7)
Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/
Requirement already satisfied: soundfile in /usr/local/lib/python3.9/dist-packages (0.12.1)
Requirement already satisfied: cffi>=1.0 in /usr/local/lib/python3.9/dist-packages (from soundfile) (1.15.1)
Requirement already satisfied: pycparser in /usr/local/lib/python3.9/dist-packages (from cffi>=1.0->soundfile) (2.21)

Test noise reduction algorithm and view steps of algorithm¶

In [3]:
#!pip install numpy==1.23.1
In [4]:
#!pip uninstall shap
In [5]:
!pip install numba==0.53
Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/
Requirement already satisfied: numba==0.53 in /usr/local/lib/python3.9/dist-packages (0.53.0)
Requirement already satisfied: setuptools in /usr/local/lib/python3.9/dist-packages (from numba==0.53) (57.4.0)
Requirement already satisfied: numpy>=1.15 in /usr/local/lib/python3.9/dist-packages (from numba==0.53) (1.23.1)
Requirement already satisfied: llvmlite<0.37,>=0.36.0rc1 in /usr/local/lib/python3.9/dist-packages (from numba==0.53) (0.36.0)
In [6]:
!pip install numba
Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/
Requirement already satisfied: numba in /usr/local/lib/python3.9/dist-packages (0.53.0)
Requirement already satisfied: setuptools in /usr/local/lib/python3.9/dist-packages (from numba) (57.4.0)
Requirement already satisfied: numpy>=1.15 in /usr/local/lib/python3.9/dist-packages (from numba) (1.23.1)
Requirement already satisfied: llvmlite<0.37,>=0.36.0rc1 in /usr/local/lib/python3.9/dist-packages (from numba) (0.36.0)
In [7]:
import IPython
from scipy.io import wavfile
import noisereduce as nr
import soundfile as sf
from noisereduce.generate_noise import band_limited_noise
import matplotlib.pyplot as plt
import urllib.request
import numpy as np
import io
%matplotlib inline

Load data¶

In [8]:
url = "https://raw.githubusercontent.com/timsainb/noisereduce/master/assets/fish.wav"
response = urllib.request.urlopen(url)
data, rate = sf.read(io.BytesIO(response.read()))
data = data
In [9]:
IPython.display.Audio(data=data, rate=rate)
Out[9]:
Your browser does not support the audio element.
In [10]:
fig, ax = plt.subplots(figsize=(20,3))
ax.plot(data)
Out[10]:
[<matplotlib.lines.Line2D at 0x7f5928c347f0>]

add noise¶

In [11]:
noise_len = 2 # seconds
noise = band_limited_noise(min_freq=2000, max_freq = 12000, samples=len(data), samplerate=rate)*10
noise_clip = noise[:rate*noise_len]
audio_clip_band_limited = data+noise
In [12]:
fig, ax = plt.subplots(figsize=(20,3))
ax.plot(audio_clip_band_limited)
Out[12]:
[<matplotlib.lines.Line2D at 0x7f592997ea60>]
In [13]:
IPython.display.Audio(data=audio_clip_band_limited, rate=rate)
Out[13]:
Your browser does not support the audio element.

Stationary remove noise¶

In [14]:
reduced_noise = nr.reduce_noise(y = audio_clip_band_limited, sr=rate, n_std_thresh_stationary=1.5,stationary=True)
In [15]:
fig, ax = plt.subplots(figsize=(20,3))
ax.plot(reduced_noise)
Out[15]:
[<matplotlib.lines.Line2D at 0x7f5929266730>]
In [16]:
IPython.display.Audio(data=reduced_noise, rate=rate)
Out[16]:
Your browser does not support the audio element.

Non-stationary noise reduction¶

In [17]:
reduced_noise = nr.reduce_noise(y = audio_clip_band_limited, sr=rate, thresh_n_mult_nonstationary=2,stationary=False)
In [18]:
fig, ax = plt.subplots(figsize=(20,3))
ax.plot(reduced_noise)
Out[18]:
[<matplotlib.lines.Line2D at 0x7f592922ceb0>]

A more difficult example¶

In [19]:
url = "https://raw.githubusercontent.com/timsainb/noisereduce/master/assets/cafe_short.wav"
response = urllib.request.urlopen(url)
noise_data, noise_rate = sf.read(io.BytesIO(response.read()))
In [20]:
fig, ax = plt.subplots(figsize=(20,4))
ax.plot(noise_data)
Out[20]:
[<matplotlib.lines.Line2D at 0x7f59291e2f40>]
In [21]:
IPython.display.Audio(data=noise_data, rate=noise_rate)
Out[21]:
Your browser does not support the audio element.

add noise to data¶

In [22]:
snr = 2 # signal to noise ratio
noise_clip = noise_data/snr
audio_clip_cafe = data + noise_clip

plot noisy data¶

In [23]:
fig, ax = plt.subplots(figsize=(20,4))
ax.plot(audio_clip_cafe)
IPython.display.Audio(data=audio_clip_cafe, rate=noise_rate)
Out[23]:
Your browser does not support the audio element.

Stationary remove noise¶

In [24]:
reduced_noise = nr.reduce_noise(y = audio_clip_cafe, sr=rate, y_noise = noise_clip, n_std_thresh_stationary=1.5,stationary=True)
In [25]:
fig, ax = plt.subplots(figsize=(20,3))
ax.plot(audio_clip_cafe)
ax.plot(reduced_noise)
Out[25]:
[<matplotlib.lines.Line2D at 0x7f592915d520>]
In [26]:
IPython.display.Audio(data=reduced_noise, rate=rate)
Out[26]:
Your browser does not support the audio element.

Non-stationary noise reduction¶

In [27]:
reduced_noise = nr.reduce_noise(y = audio_clip_cafe, sr=rate, thresh_n_mult_nonstationary=2,stationary=False)
In [28]:
fig, ax = plt.subplots(figsize=(20,3))
ax.plot(audio_clip_cafe)
ax.plot(reduced_noise, alpha = 1)
IPython.display.Audio(data=reduced_noise, rate=rate)
Out[28]:
Your browser does not support the audio element.
In [29]:
IPython.display.Audio(data=reduced_noise, rate=rate)
Out[29]:
Your browser does not support the audio element.

ensure that noise reduction does not cause distortion when prop_decrease == 0¶

In [30]:
noise_reduced = nr.reduce_noise(y=data, sr=rate, prop_decrease=0, stationary=False)
In [31]:
fig, axs = plt.subplots(nrows=2, figsize=(20,6))
axs[0].plot(data[3000:5000])
axs[0].plot(noise_reduced[3000:5000])
axs[1].plot(data)
axs[1].plot(noise_reduced)
Out[31]:
[<matplotlib.lines.Line2D at 0x7f5929136160>]
In [32]:
noise_reduced = nr.reduce_noise(y=data, sr=rate, prop_decrease=0, stationary=False)
In [33]:
fig, axs = plt.subplots(nrows=2, figsize=(20,6))
axs[0].plot(data[3000:5000])
axs[0].plot(noise_reduced[3000:5000])
axs[1].plot(data)
axs[1].plot(noise_reduced)
Out[33]:
[<matplotlib.lines.Line2D at 0x7f592908d9a0>]

Reduce noise over batches in parallel on long signal¶

In [34]:
long_data = np.tile(data, 10)
len(long_data)/rate
Out[34]:
45.47437641723356
In [35]:
fig, ax = plt.subplots(figsize=(20,4))
ax.plot(long_data)
Out[35]:
[<matplotlib.lines.Line2D at 0x7f5928faa3a0>]
In [36]:
noise = band_limited_noise(min_freq=2000, max_freq = 12000, samples=len(long_data), samplerate=rate)*10
audio_clip_band_limited = long_data+noise
In [37]:
fig, ax = plt.subplots(figsize=(20,3))
ax.plot(audio_clip_band_limited)
Out[37]:
[<matplotlib.lines.Line2D at 0x7f5928f21730>]
In [38]:
reduced_noise = nr.reduce_noise(
    y=audio_clip_band_limited,
    sr=rate,
    thresh_n_mult_nonstationary=2,
    stationary=False,
    n_jobs=2,
)
In [39]:
fig, ax = plt.subplots(figsize=(20,3))
ax.plot(audio_clip_band_limited)
ax.plot(reduced_noise)
Out[39]:
[<matplotlib.lines.Line2D at 0x7f5928eca370>]
In [40]:
reduced_noise = nr.reduce_noise(
    y=audio_clip_band_limited,
    sr=rate,
    thresh_n_mult_nonstationary=2,
    stationary=True,
    n_jobs=2,
)
In [41]:
fig, ax = plt.subplots(figsize=(20,3))
ax.plot(audio_clip_band_limited)
ax.plot(reduced_noise)
Out[41]:
[<matplotlib.lines.Line2D at 0x7f5925268280>]

Reduce noise on only a subset of a long clip¶

In [42]:
from noisereduce.noisereduce import SpectralGateStationary
In [43]:
sg = SpectralGateStationary(
    y = data,
    sr = rate,
    y_noise=None,
    prop_decrease=1.0,
    time_constant_s=2.0,
    freq_mask_smooth_hz=500,
    time_mask_smooth_ms=50,
    n_std_thresh_stationary=1.5,
    tmp_folder=None,
    chunk_size=600000,
    padding=30000,
    n_fft=1024,
    win_length=None,
    hop_length=None,
    clip_noise_stationary=True,
    use_tqdm=False,
    n_jobs=1,
)
In [44]:
subset_noise_reduce = sg.get_traces(start_frame = 10000, end_frame = 20000)
In [45]:
fig, ax = plt.subplots(figsize=(20,3))
ax.plot(subset_noise_reduce)
Out[45]:
[<matplotlib.lines.Line2D at 0x7f59291c5c10>]

Multichannel noise¶

In [46]:
audio_clip_cafe_2_channel = np.vstack([audio_clip_cafe, audio_clip_cafe])
audio_clip_cafe_2_channel.shape
Out[46]:
(2, 200542)
In [47]:
reduced_noise = nr.reduce_noise(y = audio_clip_cafe_2_channel, sr=rate, n_std_thresh_stationary=1.5,stationary=True)
In [48]:
reduced_noise.shape
Out[48]:
(2, 200542)
In [49]:
fig, axs = plt.subplots(nrows= 2, figsize=(20,5))
axs[0].plot(audio_clip_cafe_2_channel[0])
axs[1].plot(audio_clip_cafe_2_channel[1])

axs[0].plot(reduced_noise[0])
axs[1].plot(reduced_noise[1])
Out[49]:
[<matplotlib.lines.Line2D at 0x7f5929602af0>]
In [50]:
IPython.display.Audio(data=reduced_noise, rate=rate)
Out[50]:
Your browser does not support the audio element.
In [51]:
reduced_noise = nr.reduce_noise(y = audio_clip_cafe, sr=rate, thresh_n_mult_nonstationary=2,stationary=False)
In [52]:
reduced_noise.shape
Out[52]:
(200542,)
In [53]:
fig, ax = plt.subplots(figsize=(20,3))
ax.plot(audio_clip_cafe)
ax.plot(reduced_noise, alpha = 1)
IPython.display.Audio(data=reduced_noise, rate=rate)
Out[53]:
Your browser does not support the audio element.
In [53]: